package edu.towson.cosc.cosc455.nbedard.markdowncompiler;

import java.util.ArrayList;

import edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer;

public class MySyntaxAnalyzer implements SyntaxAnalyzer {

	private MyLexicalAnalyzer lexer = new MyLexicalAnalyzer();
	static ArrayList<String> parseTree = new ArrayList<String>();
	
	@Override
	public void document() throws CompilerException {
		if(!MyCompilerClass.token.equalsIgnoreCase("#START DOCUMENT")){
			String message = "A #Start Document annotation was expected when a " + 
					MyCompilerClass.token + " was found!";
			throw new CompilerException(message);
		}
		lexer.getNextToken();
		define();
		head();
		body();
		if(!MyCompilerClass.token.equalsIgnoreCase("#END DOCUMENT")){
			String message = "An #End Document annotation was expected when a " + 
					MyCompilerClass.token + " was found!";
			throw new CompilerException(message);
		}
		lexer.getNextToken();
		if(!MyCompilerClass.token.equals("")){
			String message = MyCompilerClass.token + " cannot be called after #End Document.";
			throw new CompilerException(message);
		}
		
	}

	
	public void body() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#Start Paragraph") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Bold") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Italics") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start List")||
				MyCompilerClass.token.equalsIgnoreCase("#Start Use") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Audio") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Video") ||
				MyCompilerClass.token.equalsIgnoreCase("#Newline")){
			innerText();
			paragraph();
			bold();
			italics();
			list();
			body();
		}
	}
	
	public void newline() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#Newline"))
			lexer.getNextToken();
	}
	
	@Override
	public void head() throws CompilerException{
		if(MyCompilerClass.token.equalsIgnoreCase("#START HEAD")){
			lexer.getNextToken();
			title();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END HEAD")){
				String message = "An #End Head annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}
	}

	@Override
	public void title() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START TITLE")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END TITLE")){
				String message = "An #End Title annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}

	}

	@Override
	public void paragraph() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START PARAGRAPH")){
			lexer.getNextToken();
			define();
			innerPar();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END PARAGRAPH")){
				String message = "An #End Paragraph annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}
	}
	
	public void innerText() throws CompilerException{
		if(MyCompilerClass.token.equalsIgnoreCase("#Start Use") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Audio") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Video") ||
				MyCompilerClass.token.equalsIgnoreCase("#Newline")){
			use();
			audio();
			video();
			newline();
			innerText();
		}
	}

	public void innerPar() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#Start Bold") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Italics")||
				MyCompilerClass.token.equalsIgnoreCase("#Start List") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Use") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Audio") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Video") ||
				MyCompilerClass.token.equalsIgnoreCase("#Newline")){
			innerText();
			bold();
			italics();
			list();
			innerPar();
		}
		
	}


	@Override
	public void bold() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START BOLD")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END BOLD")){
				String message = "An #End Bold annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}

	}

	@Override
	public void italics() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START ITALICS")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END ITALICS")){
				String message = "An #End Italics annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}

	}

	@Override
	public void list() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START LIST")){
			lexer.getNextToken();
			if(MyCompilerClass.token.equalsIgnoreCase("#START ITEM")){
				lexer.getNextToken();
				define();
				innerList();
				if(!MyCompilerClass.token.equalsIgnoreCase("#END ITEM")){
					String message = "An #End Item annotation was expected when a " + 
							MyCompilerClass.token + " was found!";
					throw new CompilerException(message);
				}
			}
			lexer.getNextToken();
			item();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END LIST")){
				String message = "An #End List annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
			item();
		}

	}

	@Override
	public void item() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START ITEM")){
			lexer.getNextToken();
			define();
			innerList();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END ITEM")){
				String message = "An #End Item annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
			item();
		}

	}
	
	public void innerList() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#Start Bold") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Italics")||
				MyCompilerClass.token.equalsIgnoreCase("#Start List") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Use") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Audio") ||
				MyCompilerClass.token.equalsIgnoreCase("#Start Video")){
			bold();
			italics();
			list();
			innerText();
		}
	}

	@Override
	public void audio() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START AUDIO")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END AUDIO")){
				String message = "An #End Audio annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}

	}

	@Override
	public void video() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START VIDEO")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END VIDEO")){
				String message = "An #End Video annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}

	}

	@Override
	public void define() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START DEFINE")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#NAME")){
				String message = "A #Name annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#VALUE")){
				String message = "A #Value annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END DEFINE")){
				String message = "An #End Define annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
			define();
		}

	}

	@Override
	public void use() throws CompilerException {
		if(MyCompilerClass.token.equalsIgnoreCase("#START USE")){
			lexer.getNextToken();
			if(!MyCompilerClass.token.equalsIgnoreCase("#END USE")){
				String message = "An #End Use annotation was expected when a " + 
						MyCompilerClass.token + " was found!";
				throw new CompilerException(message);
			}
			lexer.getNextToken();
		}

	}

}
